#ifndef __WRK_RECORD_H__
#define __WRK_RECORD_H__

#include <map>
#include <string>
#include <vector>
#include <inttypes.h>
#include <unistd.h>
#include <atomic>
#include <cstdint>
#include "include/wrk_core_t.h"

#define MAX_THREAD_RATE_S   1000000
using namespace std;

#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))

typedef struct {
    uint32_t connect;
    uint32_t read;
    uint32_t write;
    uint32_t status;
    uint32_t timeout;
    uint32_t biz;
} stats_errors_t;

typedef struct {
    uint64_t count;
    uint64_t limit;
    uint64_t min;
    uint64_t max;
    uint64_t data[];
} stats_t;



//统计同期内临时结点,每一次请求更新
typedef struct interval_point {
    volatile std::atomic<std::uint64_t> timestamp;
    volatile std::atomic<std::uint64_t>  requests;
    uint64_t  rt;
    uint64_t connections;
    stats_errors_t err;
}interval_point;


typedef struct stats_data {
    uint64_t requests;
    uint64_t connections;
    uint64_t latency; // us
    long double qps;
    stats_errors_t err;
}stats_data_t;

typedef struct wrk_record_t {
    uint64_t     ctime;
    uint64_t     complete;
    uint64_t     requests;
    uint64_t     wbytes;
    uint64_t     rbytes;
    uint64_t     rt;
    uint64_t     connections;
    stats_errors_t errors;
}wrk_record_t;

typedef struct statistics_t{
    stats_t *latency;
    stats_t *requests;
} statistics_t;

//定时器更新
// (timestamp, stats_data*)
typedef map<uint64_t, stats_data *> series;
typedef map<string, stats_data *> Ynode;
typedef map<uint64_t, Ynode> node;



class WrkRecord{
    private:
    map<string, series>  map_detail_data;
    map<string, struct interval_point *> interval_data; //统计时间段内的数值，做为临时变量
    vector<uint64_t> Xaxis;
    map<uint64_t, Ynode> Yaxis;
    map<string, statistics_t *> map_sta;

    void push_series(stringstream &ss, series ser);

    void push_node(stringstream &ss, uint64_t x, stats_data *p);

    string get_stats_percent();

    string get_detail_json();

    string get_stats_overview();
    
    statistics_t statistics;

    int stats_record(stats_t *sta, uint64_t n);

    stats_t *stats_alloc(uint64_t);
    void stats_free(stats_t *);

    void stats_correct(stats_t *, int64_t);


    public:
    WrkRecord();
    ~WrkRecord();
    // void add_point();

    /**
     * @name: 
     * @test: 
     * @msg: 
     * @param {type} 
     * @return: 得到请求时的detail 统计值
     */
    string get_moment_detail();
    static uint64_t time_us();

    wrk_record_t record_total;

    map<string, wrk_record_t> map_tmp_data;

    string get_stats();

    int stats_record_latency(uint64_t n);
    static long double stats_mean(stats_t *);
    static long double stats_stdev(stats_t *stats, long double);
    static long double stats_within_stdev(stats_t *, long double, long double, uint64_t);
    static uint64_t stats_percentile(stats_t *, long double);

    static uint64_t stats_popcount(stats_t *);
    static uint64_t stats_value_at(stats_t *stats, uint64_t, uint64_t *);
    
};

#endif